package api

import (
	"cgs-server/helper"
	"cgs-server/server"
	"cgs-server/server/base"
	"cgs-server/server/cgs/app/models"
	"cgs-server/server/cgs/app/models/dto"
	"cgs-server/server/cgs/app/service"
	"cgs-server/server/cgs/app/store"
	"go.mongodb.org/mongo-driver/bson"
	"net/http"
)

type WorksheetApiHandler struct {
	// srv service
	srv service.Service
	// store
	store store.Factory
}

func NewWorksheetApiHandler(store store.Factory) *WorksheetApiHandler {
	return &WorksheetApiHandler{
		srv:   service.NewService(store),
		store: store,
	}
}

func (wg *WorksheetApiHandler) GetApp(w http.ResponseWriter, r *http.Request) {
	appId := r.FormValue("appId")
	if appId == "" {
		_, _ = helper.WriteJSON(w, server.Fail("appId is required"))
		return
	}
	user, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	appData, err := wg.srv.App().Get(appId, true, true, user)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK().WithData(appData))
}

func (wg *WorksheetApiHandler) GetApiData(w http.ResponseWriter, r *http.Request) {
	data, err := models.GetApiData()
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK("Get successfully!").WithData(data))
}

func (wg *WorksheetApiHandler) GetWsInfo(w http.ResponseWriter, r *http.Request) {
	var wsInfo = struct {
		WorksheetId string `json:"worksheetId"`
	}{}
	err := helper.ReadRequestBody(&wsInfo, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	if wsInfo.WorksheetId == "" {
		_, _ = helper.WriteJSON(w, server.Fail("worksheet id is required"))
		return
	}
	user, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	ws, err := wg.srv.WorksheetInfo().Get(wsInfo.WorksheetId, user)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK().WithData(ws))
}

func (wg *WorksheetApiHandler) GetFilterRows(w http.ResponseWriter, r *http.Request) {
	param := &models.FilterParam{}
	err := helper.ReadRequestBody(param, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	if param.WorksheetId == "" {
		_, _ = helper.WriteJSON(w, server.Fail("worksheetId is required"))
		return
	}
	user, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	result, err := wg.srv.WorksheetRows().List(param, user)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, result)
}

func (wg *WorksheetApiHandler) AddRow(w http.ResponseWriter, r *http.Request) {
	if !hasWriteAuthority(r) {
		_, _ = helper.WriteJSON(w, server.Fail("Permission denied."))
		return
	}
	var wsRow models.WorksheetRow
	err := helper.ReadRequestBody(&wsRow, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	user, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	err = wg.srv.WorksheetRows().Save(&wsRow, user)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK().WithData(bson.M{"id": wsRow.GetId()}))
}

func (wg *WorksheetApiHandler) GetRowById(w http.ResponseWriter, r *http.Request) {
	rowId := r.FormValue("rowId")
	worksheetId := r.FormValue("worksheetId")
	if rowId == "" || worksheetId == "" {
		_, _ = helper.WriteJSON(w, server.Fail("rowId and worksheetId is required"))
		return
	}
	user, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	row, err := wg.srv.WorksheetRows().Get(rowId, worksheetId, user)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK().WithData(row))
}

func (wg *WorksheetApiHandler) DeleteRow(w http.ResponseWriter, r *http.Request) {
	if !hasWriteAuthority(r) {
		_, _ = helper.WriteJSON(w, server.Fail("Permission denied."))
		return
	}
	var row models.WorksheetRow
	err := helper.ReadRequestBody(&row, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	if row.RowId == "" || row.WorksheetId == "" {
		_, _ = helper.WriteJSON(w, server.Fail("rowId and worksheetId is required"))
		return
	}
	user, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	err = wg.srv.WorksheetRows().Delete(row.RowId, row.WorksheetId, user)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK())
}

func (wg *WorksheetApiHandler) EditRow(w http.ResponseWriter, r *http.Request) {
	if !hasWriteAuthority(r) {
		_, _ = helper.WriteJSON(w, server.Fail("Permission denied."))
		return
	}
	var wsRow models.WorksheetRow
	err := helper.ReadRequestBody(&wsRow, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	user, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	err = wg.srv.WorksheetRows().Update(r.Context(), &wsRow, user)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK())
}

func (wg *WorksheetApiHandler) AddRows(w http.ResponseWriter, r *http.Request) {
	if !hasWriteAuthority(r) {
		_, _ = helper.WriteJSON(w, server.Fail("Permission denied."))
		return
	}
	var wsRow models.WorksheetRows
	err := helper.ReadRequestBody(&wsRow, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	user, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	err = wg.srv.WorksheetRows().BatchAddRow(&wsRow, user)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK())
}

func (wg *WorksheetApiHandler) EditRows(w http.ResponseWriter, r *http.Request) {
	if !hasWriteAuthority(r) {
		_, _ = helper.WriteJSON(w, server.Fail("Permission denied."))
		return
	}
	var wsRow dto.BatchUpdateRow
	err := helper.ReadRequestBody(&wsRow, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	user, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	err = wg.srv.WorksheetRows().BatchUpdateRow(&wsRow, user)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK())
}
func (wg *WorksheetApiHandler) DeleteRows(w http.ResponseWriter, r *http.Request) {
	var wsRow dto.BatchUpdateRow
	err := helper.ReadRequestBody(&wsRow, w, r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	user, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	err = wg.srv.WorksheetRows().BatchDeleteRow(&wsRow, user)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK())
}

func hasWriteAuthority(r *http.Request) bool {
	v := r.Context().Value("authType")
	if v == nil {
		return false
	}
	return v.(string) == "2"
}
